package fresher.servletcontroller;

import com.vng.jcore.profiler.ProfilerLog;
import fresher.model.BillModelSingleton;
import fresher.model.ModelManager;
import fresher.objects.Bill;
import fresher.utility.DateConvertUtility;
import fresher.utility.TemplateManager;
import fresher.utility.ValidateUtility;
import hapax.Template;
import hapax.TemplateDataDictionary;
import hapax.TemplateDictionary;
import hapax.TemplateException;
import hapax.TemplateLoader;
import hapax.TemplateResourceLoader;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class BillServletController extends HttpServlet {

    private static final String STATIC_HOST = "http://localhost:8080";
    private ProfilerLog profilerLog = new ProfilerLog();

    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        //Determine type of page 
        String type = request.getParameter("type");

        profilerLog.doStartLog("doGet");

        try {
            switch (type) {
                case "index":
                    //Show all bill
                    index(request, response);
                    break;
                case "delete":
                    delete(request, response);
                    break;
                case "new":
                    //Render new bill page
                    billInsert(request, response);
                    break;

                case "insert":
                    //Process insert new bill
                    insert(request, response);
                    break;
                case "edit":
                    //Process render edit page
                    edit(request, response);
                    break;
                case "update":
                    //Process update data
                    update(request, response);
                    break;


            }
        } catch (IOException | TemplateException exception) {
        }

        profilerLog.doEndLog("doGet");
        System.out.println(profilerLog.dumpLogConsole());
    }

    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        //Determine type of page 
        String type = request.getParameter("type");
        try {
            switch (type) {
                case "index":
                    //Show all bill
                    index(request, response);
                    break;
                case "delete":
                    delete(request, response);
                    break;
                case "new":
                    //Render new bill page
                    billInsert(request, response);
                    break;

                case "insert":
                    //Process insert new bill
                    insert(request, response);
                    break;
                case "edit":
                    //Process render edit page
                    edit(request, response);
                    break;
                case "update":
                    //Process update data
                    update(request, response);
                    break;


            }
        } catch (IOException | TemplateException exception) {
        }


    }

    private void index(HttpServletRequest request,
            HttpServletResponse response) throws IOException {

        ProfilerLog profiler = new ProfilerLog();
        profiler.doStartLog("Bill Index");
        TemplateLoader templateLoader = TemplateResourceLoader.create("fresher/");
        Template template = null;
        try {
            template = templateLoader.getTemplate("/view/bill.xtm");
        } catch (TemplateException ex) {
            Logger.getLogger(BillServletController.class.getName()).log(Level.SEVERE, null, ex);
        }

        //Load dictionary
        TemplateDataDictionary dictionary = TemplateDictionary.create();

        //Process business logic 
        BillModelSingleton billModel = ModelManager.getBillModel();
        ArrayList<Bill> list = billModel.getAll();

        for (int i = 0; i < list.size(); i++) {
            //create a section to store object
            TemplateDataDictionary bills = dictionary.addSection("bills");

            //set variable to section
            Bill current = list.get(i);
            bills.setVariable("bills.id", Integer.toString(current.getId()));
            bills.setVariable("bills.tableId", Integer.toString(current.getTableId()));
            bills.setVariable("bills.date", DateConvertUtility.toString(current.getDate()));
            bills.setVariable("bills.total", Integer.toString(current.getTotal()));
        }

        //Render output 
        String content = "";
        /*try {

            content = template.renderToString(dictionary);
        } catch (TemplateException ex) {
            Logger.getLogger(BillServletController.class.getName()).log(Level.SEVERE, null, ex);
        }*/

        try {
            content = TemplateManager.getInstance().getTemplate("/view/bill.xtm").renderToString(dictionary);
        } catch (TemplateException ex) {
            ErrorServletController.showError(request, response, ex.getMessage());
        }
        response.setContentType("text/html");
        response.setStatus(HttpServletResponse.SC_OK);

        response.getWriter().println(content);
        profiler.doEndLog("Bill Index");
        System.out.println(profiler.dumpLogConsole());
    }

    private void billInsert(HttpServletRequest request,
            HttpServletResponse response) throws IOException, TemplateException {

        //Load template file
        TemplateDataDictionary dictionary = TemplateDictionary.create();

        //Render output 
        String content = "";
        try {
            content = TemplateManager.getInstance().getTemplate("/view/bill_insert.xtm").renderToString(dictionary);
        } catch (TemplateException ex) {
            ErrorServletController.showError(request, response, ex.getMessage());
        }

        response.setContentType("text/html");
        response.setStatus(HttpServletResponse.SC_OK);
        response.getWriter().println(content);
    }

    private void insert(HttpServletRequest request,
            HttpServletResponse response) throws IOException, TemplateException {

        //Process business logic 
        BillModelSingleton billModel = ModelManager.getBillModel();

        //Validate form parameters
        String formTableId = request.getParameter("table_id");
        if (!ValidateUtility.checkNull(formTableId) || !ValidateUtility.checkIsNumber(formTableId)) {
            ErrorServletController.showError(request, response, "Table id must be number and not null!");
            return;
        }
        String formDate = request.getParameter("date");
        if (!ValidateUtility.checkNull(formDate)) {
            ErrorServletController.showError(request, response, "Date must be not null!");
            return;
        }
        String formPrice = request.getParameter("price");
        if (!ValidateUtility.checkNull(formPrice) || !ValidateUtility.checkIsNumber(formPrice)) {
            ErrorServletController.showError(request, response, "Price must be number and not null!");
            return;
        }

        int tableId = Integer.parseInt(formTableId);
        long date = 0;


        try {
            date = DateConvertUtility.toInteger(formDate);
        } catch (ParseException ex) {
            Logger.getLogger(BillServletController.class.getName()).log(Level.SEVERE, null, ex);
            ErrorServletController.showError(request, response, "Date is wrong format!");
            return;
        }

        int price = Integer.parseInt(formPrice);

        billModel.insert(tableId, date, price);

        //Redirect to index page
        response.sendRedirect("/bill?type=index");
    }

    private void edit(HttpServletRequest request,
            HttpServletResponse response) throws IOException, TemplateException {

        TemplateDataDictionary dictionary = TemplateDictionary.create();

        //Process business logic
        int id = Integer.parseInt(request.getParameter("id"));
        BillModelSingleton billModel = ModelManager.getBillModel();
        Bill bill = billModel.getBill(id);

        dictionary.setVariable("id", Integer.toString(id));
        dictionary.setVariable("tableId", Integer.toString(bill.getTableId()));
        dictionary.setVariable("date", DateConvertUtility.toString(bill.getDate()));
        dictionary.setVariable("price", Integer.toString(bill.getTotal()));


        //Render output 
        String content = "";
        try {
            content = TemplateManager.getInstance().getTemplate("/view/bill_edit.xtm").renderToString(dictionary);
        } catch (TemplateException ex) {
            ErrorServletController.showError(request, response, ex.getMessage());
        }

        response.setContentType("text/html");
        response.setStatus(HttpServletResponse.SC_OK);
        response.getWriter().println(content);
    }

    private void update(HttpServletRequest request,
            HttpServletResponse response) throws IOException, TemplateException {

        //Process business logic 
        BillModelSingleton billModel = ModelManager.getBillModel();
        String formTableId = request.getParameter("table_id");

        //Validate form parameter
        if (!ValidateUtility.checkNull(formTableId) || !ValidateUtility.checkIsNumber(formTableId)) {
            ErrorServletController.showError(request, response, "Table id must be number and not null!");
            return;
        }
        String formDate = request.getParameter("date");
        if (!ValidateUtility.checkNull(formDate)) {
            ErrorServletController.showError(request, response, "Date must be not null!");
            return;
        }
        String formPrice = request.getParameter("price");
        if (!ValidateUtility.checkNull(formPrice) || !ValidateUtility.checkIsNumber(formPrice)) {
            ErrorServletController.showError(request, response, "Price must be number and not null!");
            return;
        }

        int id = Integer.parseInt(request.getParameter("id"));
        int tableId = Integer.parseInt(formTableId);
        long date = 0;
        try {
            date = DateConvertUtility.toInteger(formDate);
        } catch (ParseException exception) {
            ErrorServletController.showError(request, response, "Date is wrong format!");
        }

        int price = Integer.parseInt(formPrice);
        billModel.update(id, tableId, date, price);

        //Redirect to index page
        response.sendRedirect("/bill?type=index");
    }

    private void delete(HttpServletRequest request,
            HttpServletResponse response) throws IOException, TemplateException {

        //Process business logic 
        BillModelSingleton billModel = ModelManager.getBillModel();
        int id = Integer.parseInt(request.getParameter("id"));
        billModel.delete(id);

        //Redirect to index page
        response.sendRedirect("/bill?type=index");
    }
}